//
//
//  Created by 乐启榜 on 16/8/5.
//  Copyright © 2016年 乐启榜. All rights reserved.
//

import UIKit

class QBTitleLabel: UILabel {
    
    var scale: CGFloat = 0.0 {
        didSet{
            self.textColor = UIColor(red: scale, green: 0.0, blue: 0.0, alpha: 1.0)
            
            let minScale: CGFloat  = 0.8
            let trueScale: CGFloat = minScale + (1 - minScale) * scale
            self.transform = CGAffineTransformMakeScale(trueScale, trueScale)
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

enum QBMenuViewOptions {
    case menuBackgroundColor(UIColor)
    case menuHeigth(CGFloat)
    
    case isSelectionIndicator(Bool)
    case selectionIndicatorColor(UIColor)
    case selectionIndicatorHeight(CGFloat)
    
    case isRightButton(Bool)
    case rightButtonWidth(CGFloat)
    case rightButtonBackgroundColor(UIColor)
    
    case menuItemSpace(CGFloat)
    case menuItemNormalColor(UIColor)
    case menuItemFont(UIFont)
    case menuItemDefaultIndex(Int)
    
    case animationDuration(NSTimeInterval)
}

//MARK: - Delegate && DataSource Method
protocol QBMenuMainViewDelegate: class {
    
    func menuMainView(didSelectedWithIndex index: Int)
    
}
protocol QBMenuMainViewDataSource: class {
    // 去标题数量
    func numberOfTitlesInMenu(menu: QBMenuMainView) -> Int
    // 取标题
    func dropDownMenu(menu: QBMenuMainView,titleForIndex index: Int) -> String
    
}
// MARK: - class
class QBMenuMainView: UIView {
    
    var menuBackgroundColor: UIColor = UIColor.whiteColor()
    var menuHeigth: CGFloat = 44
    
    var isSelectionIndicator: Bool = true
    var selectionIndicatorColor: UIColor = UIColor.redColor()
    var selectionIndicatorHeight: CGFloat = 3
    
    var isRightButton: Bool = true
    var rightButtonWidth: CGFloat = 30
    var rightButtonBackgroundColor: UIColor = UIColor.whiteColor()
    
    var menuItemSpace: CGFloat = 15
    var menuItemNormalColor: UIColor = UIColor.lightGrayColor()
    var menuItemFont: UIFont = UIFont.systemFontOfSize(19)
    var menuItemWidth: CGFloat = 0
    var menuItemWidths: [CGFloat] = []
    var menuItemDefaultIndex: Int = 0
    
    var animationDuration: NSTimeInterval = 0.2
    
    weak var delegate: QBMenuMainViewDelegate?
    weak var dataSource: QBMenuMainViewDataSource?{
        didSet{
            // dataSource设置之后才配置UI界面
            configUserInterface()
        }
    }
    
    // 当rootViewController的ControllerScrollview发生滚动时，menuScrollview的动画效果发生相对应变化
    var pageContentOffsetX: CGFloat = 0.0{
        didSet{
            weak var weakSelf = self
            guard let _weakSelf = weakSelf else{return}
            // 下划线、字体动画效果发生变化完成后，再设置menuScrollview的偏移
            menuViewTitleAnimation(ControllerScrollViewcontentOffsetX: pageContentOffsetX) { (index) in
                _weakSelf.menuScrollWithIndex(index)
            }
        }
    }
    
    // 重写frame，主要是为了在didLayoutView时重新各个subview的frame
    override var frame: CGRect {
        didSet{
            
            if isRightButton {
                
                if _backgroundView != nil{
                    _backgroundView.frame = CGRect(x: 0, y: 0, width: frame.width - self.rightButtonWidth, height: frame.height)
                }
                
                if _rightButton != nil{
                    _rightButton.frame = CGRect(x: frame.width - self.rightButtonWidth, y: 0, width: self.rightButtonWidth, height: frame.height)
                }
                
            } else {
                
                if _backgroundView != nil{
                    _backgroundView.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
                }
                
            }
            
            if _menuScrollView != nil{
                
                let width: CGFloat = _menuScrollView.contentSize.width - self.frame.width
                
                if width <= 0 {
                    
                    _menuScrollView.center = _backgroundView.center
                    _menuScrollView.bounds = CGRect(x: 0, y: 0, width: _menuScrollView.contentSize.width, height: _backgroundView.frame.height)
                    
                }else if width > 0 {
                    
                    _menuScrollView.frame = CGRect(x: 0, y: 0, width: _backgroundView.frame.width, height: _backgroundView.frame.height)
                    
                }
                
                menuScrollWithIndex(_oldSelectedIndex)
            }
        }
    }
    
    private var _backgroundView: UIView!
    private var _menuScrollView: UIScrollView!
    private var _rightButton: UIButton!
    private var _menuIndicatorView: UIView?
    private var _oldSelectedIndex: Int = 0
    
    private var _lastIndex: Int = 0
    private var _swipingContenOffsetx: CGFloat = 0.0
    private var _swipingIndex: Int = 0
    private var _itemWidhtOfRight: CGFloat = 0.0
    private var _isTapMenuTitleScroll: Bool = false
    
    
    init(frame: CGRect, options: [QBMenuViewOptions]?) {
        super.init(frame: frame)
        
        guard let _options = options else {return}
        for _option in _options {
            switch _option {
            case let .menuBackgroundColor(value):
                menuBackgroundColor = value
            case let .menuHeigth(value):
                menuHeigth = value
            case let .isSelectionIndicator(value):
                isSelectionIndicator = value
            case let .selectionIndicatorColor(value):
                selectionIndicatorColor = value
            case let .selectionIndicatorHeight(value):
                selectionIndicatorHeight = value
                
            case let .isRightButton(value):
                isRightButton = value
            case let .rightButtonWidth(value):
                rightButtonWidth = value
            case let .rightButtonBackgroundColor(value):
                rightButtonBackgroundColor = value
                
            case let .menuItemSpace(value):
                menuItemSpace = value
            case let .menuItemNormalColor(value):
                menuItemNormalColor = value
            case let .menuItemFont(value):
                menuItemFont = value
            case let .menuItemDefaultIndex(value):
                menuItemDefaultIndex = value
                
            case let .animationDuration(value):
                animationDuration = value
            }
        }
        
        setupUserInterface()
        
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 设置UI界面
    func setupUserInterface() {
        self.userInteractionEnabled = true
        
        let _width: CGFloat = self.frame.width
        let _height: CGFloat = self.frame.height
        
        if isRightButton {
            
            _backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: (_width - self.rightButtonWidth), height:_height))
            _backgroundView.backgroundColor = UIColor.clearColor()
            self.addSubview(_backgroundView)
            
            _rightButton = UIButton(type: .Custom)
            _rightButton.frame = CGRect(x: _backgroundView.frame.width, y: 0, width: self.rightButtonWidth, height: _height)
            _rightButton.setTitle("+", forState: .Normal)
            _rightButton.setTitleColor(self.menuItemNormalColor, forState: .Normal)
            _rightButton.addTarget(self, action: #selector(QBMenuMainView.rightButtonAction(_:)), forControlEvents: .TouchUpInside)
            _rightButton.backgroundColor = self.menuBackgroundColor
            self.addSubview(_rightButton)
            
        }else{
            
            _backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: _width, height:_height))
            _backgroundView.backgroundColor = UIColor.clearColor()
            self.addSubview(_backgroundView)
        }
        
        
        _menuScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: _backgroundView.frame.width, height: _backgroundView.frame.height))
        _menuScrollView.backgroundColor = self.menuBackgroundColor
        _backgroundView.addSubview(_menuScrollView)
        _menuScrollView.showsVerticalScrollIndicator = false
        _menuScrollView.showsHorizontalScrollIndicator = false
        _menuScrollView.translatesAutoresizingMaskIntoConstraints = false
        
    }
    
    // 配置UI界面
    func configUserInterface() {
        
        for view in _menuScrollView.subviews {
            view.removeFromSuperview()
        }
        
        // 在scrollView上只添加一个手势，不给label添加手势，处理点击事件详见“handleMenuItemTap”方法
        let menuItemTapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleMenuItemTap(_: )))
        menuItemTapGestureRecognizer.numberOfTapsRequired = 1
        menuItemTapGestureRecognizer.numberOfTouchesRequired = 1
        menuItemTapGestureRecognizer.delegate = self
        _menuScrollView.addGestureRecognizer(menuItemTapGestureRecognizer)
        
        guard let _dataSource = dataSource else {return}
        
        let itemCount = _dataSource.numberOfTitlesInMenu(self)
        
        var totalMenuContentWidth: CGFloat = 0.0
        for index in 0..<itemCount {
            
            var menuItemFrame: CGRect = CGRect()
            
            // 获取label的title
            let controllerTitle: String? = _dataSource.dropDownMenu(self, titleForIndex: index)
            
            // 如果用户没有设置标题，则默认为 Menu1...
            let titleText: String = controllerTitle != nil ? controllerTitle! : "Meun\(index + 1)"
            
            // 在设置文本的字体大小时，有一个坑： 不能设置小字体再让字体变大；应该先设置最大的字体，再让字体变小
            // let titleWidthCGRect: CGSize = index == menuItemDefaultIndex ? titleText.qb_stringSizeWithFont(menuItemSelectedFont) : titleText.qb_stringSizeWithFont(menuItemSelectedFont)
            
            
            // 计算字体大小
            let titleWidthCGRect: CGSize = titleText.qb_stringSizeWithFont(self.menuItemFont)
            
            menuItemWidth = titleWidthCGRect.width
            
            // 保存字体大小
            menuItemWidths.append(menuItemWidth)// 保存字体size
            
            if !self.isSelectionIndicator{
                menuItemFrame = CGRect(x: totalMenuContentWidth + self.menuItemSpace, y: 0, width: menuItemWidth, height: self.menuHeigth)
            }else{
                menuItemFrame = CGRect(x: totalMenuContentWidth + self.menuItemSpace, y: 0, width: menuItemWidth, height: self.menuHeigth - self.selectionIndicatorHeight)
              
            }
            
            let menuItem: QBTitleLabel = QBTitleLabel(frame: menuItemFrame)
            
            menuItem.text = titleText
            
            menuItem.font = self.menuItemFont
            
            menuItem.textColor = self.menuItemNormalColor
            
            menuItem.textAlignment = .Center
            
            menuItem.adjustsFontSizeToFitWidth = true
            
            _menuScrollView.addSubview(menuItem)
            
            
            // 计算_menuScrollView的contentSize
            totalMenuContentWidth += (menuItemWidth + self.menuItemSpace)
            
            // 再最后添加上第一个label距scrollview左边的间隔以及最后一个label距scrollview右边的间隔
            if index == itemCount - 1{
                
                totalMenuContentWidth += (self.menuItemSpace * 2)
            }
            
            // 设置默认选择下标的状态
            if index == self.menuItemDefaultIndex {
                menuItem.scale = 1.0
                _oldSelectedIndex = index// 保存当前下标
            }else{
                menuItem.scale = 0.0
            }
            
        }
        
        _menuScrollView.contentSize = CGSize(width: totalMenuContentWidth, height: 0)
        
        // 设置下划线
        if self.isSelectionIndicator {
                
            _menuIndicatorView = UIView()
            
            guard let _indicatorView = _menuIndicatorView else {return}
            _indicatorView.backgroundColor = self.selectionIndicatorColor
            _indicatorView.frame
                    = CGRect(x: self.menuItemSpace,
                             y: _menuScrollView.frame.height - self.selectionIndicatorHeight,
                             width: menuItemWidths[self.menuItemDefaultIndex],
                             height: self.selectionIndicatorHeight)
            _menuScrollView.addSubview(_indicatorView)
        }
    
    }
    
    // 右侧按钮点击事件
    func rightButtonAction(sender: UIButton){
        
//        print("isclicked")
        
    }
    
    // 处理点击事件
    func handleMenuItemTap(gestureRecognizer: UITapGestureRecognizer) {
    
        // 1、获取手指点击位置
        let tappedPoin: CGPoint = gestureRecognizer.locationInView(_menuScrollView)
        
        // 2、判断点击位置在scrollview高度之内
        if tappedPoin.y < _menuScrollView.frame.height {
            
            // 3、循环遍历meunItemWidths，计算出点击在哪个label上；
            //   分别计算出label左右的距离scrollview左边的width
            //   itemLeftPointX < tappedPoin.x < itemRightPointX,满足这个条件，则相对应的下标为选中的下标
            var itemLeftPointX: CGFloat = 0.0
            var itemRightPointX: CGFloat = 0.0
            for (index, width) in menuItemWidths.enumerate() {
                
                itemLeftPointX = itemRightPointX + self.menuItemSpace
                itemRightPointX = itemLeftPointX + width
            
                if itemLeftPointX < tappedPoin.x && tappedPoin.x < itemRightPointX {

                    _isTapMenuTitleScroll = true
                    delegate?.menuMainView(didSelectedWithIndex: index)

                    break
                }
            }
        }
    }
    
    // 处理字体、下划线的动画效果跟随点击事件和滑动事件
    // 需要分别处理：1、手指点击时的动画效果；2、RootControllerView中ControllerScrollview滑动时的动画效果
    // 字体动画效果为放大缩小的效果。采用的scale，而不是直接设置font
    // 下划线动画效果直接设置frame
    private func menuViewTitleAnimation(ControllerScrollViewcontentOffsetX contentOffsetX: CGFloat, complete: (index: Int)-> Void) {
        
        // 1）、获取绝对值 abs是获取绝对值，例如：|-10| = 10
        // 以第一个label滑动到第二label为例：
        /*
         value的值
         0.00933333333333333,0.038666666666666,0.0786666666666667 ... 0.997333333333333,1.0
         */
        let value: CGFloat = abs(contentOffsetX / UIScreen.mainScreen().bounds.width)
        
        // 2）、处理Controllerscrollview滑动时的效果
        if !_isTapMenuTitleScroll {
            
            /*
             letfIndex的值： 0，0，0...0,1
             rightIndex的值：1，1，1...1,2
             */
            // 1、计算左右两边label的scale
            let leftIndex: Int = Int(value)
            
            let rightIndex: Int = leftIndex + 1
            
            let scaleRight: CGFloat = value - CGFloat(leftIndex)
            
            let scaleLeft: CGFloat = 1 - scaleRight
            
            // 设置scale
            let titleLabel = _menuScrollView.subviews[leftIndex] as! QBTitleLabel
            
            titleLabel.scale = scaleLeft
            
            if rightIndex < _menuScrollView.subviews.count {
                
                let titleLabel = _menuScrollView.subviews[rightIndex] as? QBTitleLabel
                
                guard let _titleLabel = titleLabel else{return}
                
                _titleLabel.scale = scaleRight
            }
            
            // 2、处理下划线
                // 手指向左滑动，即视图 0 1 2 3 4 顺序出现
                // 处理一个坑： 上面定义的rightIndex = leftIndex + 1的原因，如果不做处理直接使用rightIndex，在滑动结束时，下划线不会出现在选中的下边下，而是下一个的label下，例如：我们选中了2这个下标的label，理想的状态下，下划线应该出现在2的这个下方，当结果在滚动结束后出现在了3的这个label的下方
                // 在滑动的时候是正常显示的；
                // 处理逻辑： 保存滑动时候的右边rightIndex下标到_swipingIndex，判断_swipingIndex == leftIndex 则表示滑动结束，滑动结束后使用_swipingIndex
            if contentOffsetX > _swipingContenOffsetx {
                    
                if _swipingIndex == leftIndex {
                        
                    indicationViewAnimation(_swipingIndex)
                    _oldSelectedIndex = _swipingIndex
                        
                }else{
                        
                    indicationViewAnimation(rightIndex)
                    
                }
                _swipingIndex = rightIndex
                
                // 手指先右边滑动，即视图： 4 3 2 1 0 顺序出现
            }else if contentOffsetX < _swipingContenOffsetx {
                    
                indicationViewAnimation(leftIndex)
                
                _oldSelectedIndex = leftIndex
            }
                
            _swipingContenOffsetx = contentOffsetX

            
        // 3）、处理手指点击时的动画效果
        } else {
            
            let tapIndex: Int = Int(value)
            let titleLabel = _menuScrollView.subviews[tapIndex] as! QBTitleLabel
            titleLabel.scale = 1.0
            
            let oldtitleLabel = _menuScrollView.subviews[_oldSelectedIndex] as! QBTitleLabel
            oldtitleLabel.scale = 0.0
            
            if self.isSelectionIndicator {
                
                indicationViewAnimation(tapIndex)
                
            }
            
            _oldSelectedIndex = tapIndex
            _isTapMenuTitleScroll = false
        }
        
        // 动画效果结束后，block返回，进行处理contentoffsetx的事件
        complete(index: _oldSelectedIndex)
    }
    // 下滑线动画效果控制
    private func indicationViewAnimation(index: Int){
        
        weak var weakSelf = self
        guard let _weakSelf = weakSelf else{return}
        
        guard let _indicatorView = _menuIndicatorView else {return}
        
        var contentOffsetX: CGFloat = 0.0
        for i in 0..<index {
            
            contentOffsetX += menuItemWidths[i] + self.menuItemSpace
        }
            
        UIView.animateWithDuration(animationDuration, animations: {
            _indicatorView.frame
                = CGRect(x: contentOffsetX + _weakSelf.menuItemSpace,
                         y:_weakSelf._menuScrollView.frame.height - _weakSelf.selectionIndicatorHeight,
                     width: _weakSelf.menuItemWidths[index],
                    height: _weakSelf.selectionIndicatorHeight)
        })
    }
    
    // menuScrollview跟随点击滚动偏移
    private func menuScrollWithIndex(index: Int){
        
        let menuScrollViewHaleWidth: CGFloat = _menuScrollView.bounds.width / 2
        
        // 当前根据下标得到的偏移量
        var currentContentOffsetxOfIndex: CGFloat = 0.0
        for i in 0..<index {
            
            currentContentOffsetxOfIndex += (menuItemWidths[i] + self.menuItemSpace)
        }
        currentContentOffsetxOfIndex += menuItemWidths[index] / 2
        
        // 总的偏移量 = 当前根据下标得到的偏移量 - 滚动视图1/2的宽度
        let totalContentOffsetx = currentContentOffsetxOfIndex - menuScrollViewHaleWidth

        var contentOffsetx: CGFloat = 0.0
        
        // 判断：
        // 一、如果总的偏移量小于0，设置偏移量为0
        // 二、如果总的偏移量大于0，
        // 1、 不大于menuscrollview的总偏移量，则偏移量等于总的偏移量
        // 2、 大于menuscrollview的总偏移量，则偏移量等于menuscrollview的总偏移量
        if  totalContentOffsetx < 0 {
            
            contentOffsetx = 0
            
        }else if totalContentOffsetx > 0{
            
            let totalMenuScrollViewContentoffsetx: CGFloat = _menuScrollView.contentSize.width - _menuScrollView.bounds.width
            
            if totalContentOffsetx > totalMenuScrollViewContentoffsetx {
                
                contentOffsetx = totalMenuScrollViewContentoffsetx
                
            }else {
                
                contentOffsetx = totalContentOffsetx
                
            }
        }
        // 设置偏移量
        weak var weakSelf = self
        guard let _weakSelf = weakSelf else{return}
        UIView.animateWithDuration(self.animationDuration) {
            _weakSelf._menuScrollView.contentOffset = CGPoint(x: contentOffsetx, y: 0)
        }
        
    }
    
    
    //**************************************下拉菜单动画效果************************************
    private func keyWindow() -> UIWindow{
        return UIApplication.sharedApplication().keyWindow!
    }
    
    private func screenBounds() -> CGRect{
        return self.keyWindow().bounds
    }
    
    private func animationOfDropDownMenu(backgroundView backgroundView: UIView, dropDownMenuView: UITableView, show: Bool, compelete:()->Void){
        
        weak var weakSelf = self
        guard let _weakSelf = weakSelf else{return}
        
        animationOfBackgroundView(backgroundView, show: show) {
            
            _weakSelf.animationOfScrollView(dropDownMenuView, show: show, compelete: {
                
            })
        }
        
        compelete()
    }
    
    private func animationOfBackgroundView(backgroundView: UIView,  show: Bool, compelete: ()-> Void){
//        weak var weakSelf = self
//        guard let _weakSelf = weakSelf else{return}
        
        if show == true {
            
//            keyWindow().addSubview(backgroundView)
//            backgroundView.snp_makeConstraints(closure: { (make) in
//                make.top.equalTo(_weakSelf.snp_bottom)
//                make.left.right.bottom.equalTo(_weakSelf.keyWindow())
//            })
//            backgroundView.layoutIfNeeded()
//            
//            UIView.animateWithDuration(0.3, animations: {
//                backgroundView.backgroundColor = UIColor(white: 0.7, alpha: 0.3)
//            })
            
        } else {
            
            UIView.animateWithDuration(0.3, animations: {
                backgroundView.backgroundColor = UIColor(white: 0.0, alpha: 0.0)
                }, completion: { (didFinish) in
                    backgroundView.removeFromSuperview()
            })
            
        }
        compelete()
    }
    
    private func animationOfScrollView(scrollView: UIScrollView, show: Bool, compelete: ()-> Void){
        
//        weak var weakSelf = self
//        guard let _weakSelf = weakSelf else{return}
        
        if show == true {
//            keyWindow().addSubview(scrollView)
//            scrollView.snp_makeConstraints(closure: { (make) in
//                make.top.equalTo(_weakSelf.snp_bottom).offset(1)
//                make.right.equalTo(_weakSelf.keyWindow())
//                make.width.equalTo(120)
//                make.height.equalTo(350)
//            })
            
        }else{
            
            scrollView.removeFromSuperview()
            
        }
        
    }
    //**************************************下拉菜单动画效果截止************************************

}
// MARK: - DataSource && Delegate
extension QBMenuMainView:  UITableViewDelegate, UITableViewDataSource,UIGestureRecognizerDelegate{
    
    
    // TableViewDataSource
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return 0
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        
        var cell = tableView.dequeueReusableCellWithIdentifier("cell")
        if (cell == nil){
            cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
        }

        return cell!
    }
    
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 50
    }
    
    // UITableviewDelegate
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        
        
    }
}


extension String{
    
    func qb_stringSize(font: UIFont, maxWidth: CGFloat, maxHeight: CGFloat) -> CGSize{
        let arrt: Dictionary<String, UIFont> = [NSFontAttributeName: font]
        let maxSize: CGSize = CGSize(width: maxWidth, height: maxHeight)
        let options: NSStringDrawingOptions = [.TruncatesLastVisibleLine,.UsesLineFragmentOrigin,.UsesFontLeading]
        return self.boundingRectWithSize(maxSize, options: options, attributes: arrt, context: nil).size
    }
    
    func qb_stringSizeWithFont(font: UIFont) -> CGSize{
        return qb_stringSize(font, maxWidth: 0, maxHeight: 0)
    }
}























